/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */


import radio from '@ohos.telephony.radio';
import wifi from '@ohos.wifi';
import connection from '@ohos.net.connection'

import Alarm from './Alarm'
import NetStatusUtil from './NetStatusUtil'
import NetworkSignalUtil from './NetworkSignalUtil'
import WakerLock from './WakerLock'
import { Callback } from '@ohos.base';

/**
 * mars获取
 * Created by caoshaokun on 16/3/7.
 */
class PlatformComm {
  private static readonly TAG: String = "PlatformComm";
  private static readonly IS_PROXY_ON: boolean = false;

  //  public static Handler handler = null;

  static readonly ENoNet: number = -1;
  static readonly EWifi: number = 1;
  static readonly EMobile: number = 2;
  static readonly EOtherNet: number = 3;
  static readonly NETTYPE_NOT_WIFI: number = 0;
  static readonly NETTYPE_WIFI: number = 1;
  static readonly NETTYPE_WAP: number = 2;
  static readonly NETTYPE_2G: number = 3;
  static readonly NETTYPE_3G: number = 4;
  static readonly NETTYPE_4G: number = 5;
  static readonly NETTYPE_5G: number = 6;
  static readonly NETTYPE_UNKNOWN: number = 7;
  static readonly NETTYPE_NON: number = -1;

  /**
   * WiFi信息类
   */
  static WifiInfo = class {
    public ssid: String;
    public bssid: String;
  }

  /**
   * 手机卡信息类
   */
  static SIMInfo = class {
    public ispCode: String;
    public ispName: String;
  }

  /**
   * 接入点信息
   */
  static APNInfo = class {
    public netType: number;
    public subNetType: number;
    public extraInfo: String;
  }

  public static init(): void {
    NetworkSignalUtil.InitNetworkSignalUtil();
  }

  public static C2JS = class {
    static NETWORK_TYPE_UNKNOWN: number = 0;

    /**
     * mars回调获取网络类型
     * @return WiFi/Mobile/NoNet
     */
    public static getNetInfo(callback: Callback<number>): void{
      NetStatusUtil.getNetType((data) => {
        if (data == NetStatusUtil.NETWORK_TYPE_WIFI) {
          callback(PlatformComm.EWifi)
        } else if (data != radio.NetworkType.NETWORK_TYPE_UNKNOWN) {
          callback(PlatformComm.EMobile)
        } else {
          callback(PlatformComm.ENoNet)
        }
      })
    }

    /**
     * mars回调获取Http代理信息
     * @param strProxy
     * @return
     */
    public static getProxyInfo(strProxy: string, callback: Callback<number>): void {
      connection.getDefaultNet().then(function (netHandle) {
        connection.getConnectionProperties(netHandle, function (error, info) {
          console.log(JSON.stringify(error))
          console.log(JSON.stringify(info))
          let proxyPort = info.dnses[0].port
          strProxy.concat(proxyPort.toString())
          callback(proxyPort);

        })
      })
    }

    public static getStatisticsNetType(callback: Callback<number>): void {
      NetStatusUtil.getNetType((number) => {
        callback(number)
      });
    }

    /**
     * 启动定时器
     * @param type
     * @param id
     * @param after
     * @return
     */
    public static startAlarm(type: number, id: number, after: number): boolean {
      return Alarm.start(id, after)

    }

    /**
     * 停止定时器
     * @param id
     * @return
     */
    public static stopAlarm(id: number): boolean {
      return Alarm.stop(id);
    }

    /**
     * 获取当前WiFi的具体信息
     * @return
     */
    public static getCurWifiInfo(callback: Callback<InstanceType<typeof PlatformComm.WifiInfo>>): void {
      if (NetStatusUtil.isWifi()) {
        wifi.getLinkedInfo().then(data => {
          console.info("get wifi linked info: " + JSON.stringify(data));
          if (data != null && data.bssid != null) {
            let wifiInfo: InstanceType<typeof PlatformComm.WifiInfo> = new PlatformComm.WifiInfo();
            wifiInfo.ssid = data.ssid;
            wifiInfo.bssid = data.bssid;
            callback(wifiInfo);
          } else {
            callback(null);
          }
        }).catch(error => {
          console.info("get wifi linked info error. Caused:" + error);
          callback(null);
        });
      }
    }

    /**
     * 获取当前手机卡信息
     * @return
     */
    public static getCurSIMInfo(callback: Callback<InstanceType<typeof PlatformComm.SIMInfo>>): void  {
      NetStatusUtil.getISPCode((ispCode) => {
        if (NetStatusUtil.NO_SIM_OPERATOR == ispCode) {
          callback(null);
        }
        let simInfo: InstanceType<typeof PlatformComm.SIMInfo> = new PlatformComm.SIMInfo();
        simInfo.ispCode = '' + ispCode;
        NetStatusUtil.getISPName((codeName) => {
          simInfo.ispName = codeName
          callback(simInfo);
        });
      })
    }

    /**
     * 获取接入点信息
     * @return
     */
    public static getAPNInfo(callback: Callback<InstanceType<typeof PlatformComm.APNInfo>>): void{
      NetStatusUtil.getNetType((data) => {
        let apnInfo: InstanceType<typeof PlatformComm.APNInfo> = new PlatformComm.APNInfo();
        apnInfo.netType = data
        //TODO  这个验证有问题
        radio.getRadioTech(0, (err, radioTech) => {
          console.log(`callback: err->${JSON.stringify(err)}, data->${JSON.stringify(data)}`);
          apnInfo.subNetType = radioTech.csRadioTech.valueOf();
          if (data != NetStatusUtil.NETWORK_TYPE_WIFI) {
            switch (data) {
              case radio.NetworkType.NETWORK_TYPE_UNKNOWN:
                apnInfo.extraInfo = "none"
                break
              case radio.NetworkType.NETWORK_TYPE_GSM:
              case radio.NetworkType.NETWORK_TYPE_CDMA:
                apnInfo.extraInfo = "2g"
                break
              case radio.NetworkType.NETWORK_TYPE_WCDMA: //3g 联通通讯标准
                apnInfo.extraInfo = "3g"
                break
              case radio.NetworkType.NETWORK_TYPE_TDSCDMA: // 3g
                apnInfo.extraInfo = "3g"
                break
              case radio.NetworkType.NETWORK_TYPE_LTE: //3g 和4g 过度的标准
                apnInfo.extraInfo = "4g"
                break
              case radio.NetworkType.NETWORK_TYPE_NR: // 5g
                apnInfo.extraInfo = "5g"
                break
              default:
                break
            }
          } else {
            PlatformComm.C2JS.getCurWifiInfo((instanceType) => {
              apnInfo.extraInfo = instanceType.ssid;
            })
          }
          callback(apnInfo)
        });
      })
    }

    public static getCurRadioAccessNetworkInfo(callback: Callback<number>): void  {
      NetStatusUtil.getNetType((data) => {
        callback(data);
      })
    }

    /**
     * mars回调获取网络信号强度
     * @param isWifi
     * @return
     */
    public static getSignal(isWifi: boolean, callback: Callback<number>): void {
      if (isWifi) {
        NetworkSignalUtil.getWifiSignalStrength((signal) => {
          callback(signal)
        });
      } else {
        callback(NetworkSignalUtil.getGSMSignalStrength());
      }
    }

    /**
     * mars回调查看终端网络是否已连接状态
     * @return
     */
    public static isNetworkConnected(callback: Callback<boolean>): void {
      NetStatusUtil.isNetworkConnected((isNetworkConnected) => {
        callback(isNetworkConnected)
      });
    }

    public static wakeupLock_new(): WakerLock {
      return new WakerLock();
    }
  }
}

export default PlatformComm;